package com.library.service.Impl;


import com.library.context.BaseContext;
import com.library.dto.ReviewDTO;
import com.library.entity.BookReviews;
import com.library.mapper.BookMapper;
import com.library.mapper.BookReviewsMapper;
import com.library.mapper.UserMapper;
import com.library.service.ReviewService;
import com.library.vo.BookReviewsVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ReviewServiceImpl implements ReviewService {

    @Autowired
    private BookReviewsMapper bookReviewsMapper;
    @Autowired
    private BookMapper bookMapper;
    @Autowired
    private UserMapper userMapper;

    @Override
    public void save(ReviewDTO reviewDTO,Long bookId) {
        if(reviewDTO.getBookId() == null) {
            reviewDTO.setBookId(bookId);
        }
        if(reviewDTO.getUserId() == null){
            reviewDTO.setUserId(BaseContext.getCurrentId());
        }
        if(reviewDTO.getBookTitle() == null){
            reviewDTO.setBookTitle(bookMapper.getBookByBookId(bookId).getTitle());
        }
        if(reviewDTO.getParentReviewId() == null){
            reviewDTO.setParentReviewId(0L);
        }
        if(reviewDTO.getUsername() == null){
            reviewDTO.setUsername(userMapper.getById(reviewDTO.getUserId()).getUsername());
        }
        BookReviews bookReviews = new BookReviews();
        //属性拷贝
        BeanUtils.copyProperties(reviewDTO,bookReviews);
        bookReviews.setCreateTime(LocalDateTime.now());
        bookReviewsMapper.save(bookReviews);

    }

    @Override
    public void reply(ReviewDTO reviewDTO, Long reviewId) {
        if(reviewDTO.getUserId() == null){
            reviewDTO.setUserId(BaseContext.getCurrentId());
        }
        if(reviewDTO.getBookTitle() == null){
            reviewDTO.setBookTitle(bookMapper.getBookByBookId(reviewDTO.getBookId()).getTitle());
        }
        if(reviewDTO.getParentReviewId() == null) {
            reviewDTO.setBookId(reviewId);
        }
        if(reviewDTO.getUsername() == null){
            reviewDTO.setUsername(userMapper.getById(reviewDTO.getUserId()).getUsername());
        }
        BookReviews bookReviews = new BookReviews();
        //属性拷贝
        BeanUtils.copyProperties(reviewDTO,bookReviews);
        bookReviews.setCreateTime(LocalDateTime.now());
        bookReviewsMapper.save(bookReviews);
    }

    @Override
    public void delete(Long reviewId) {
        //如果该评论有子评论，则删除子评论
        // 递归删除所有子评论
        deleteChildrenRecursively(reviewId);

        bookReviewsMapper.deleteById(reviewId);
    }

    private void deleteChildrenRecursively(Long parentReviewId) {
        // 查询直接子评论
        List<Long> childIds = bookReviewsMapper.selectChildReviewIds(parentReviewId);
        for (Long childId : childIds) {
            // 递归删除子评论的后代
            deleteChildrenRecursively(childId);
            // 删除当前子评论
            bookReviewsMapper.deleteById(childId);
        }
    }

    @Override
    public List<BookReviewsVO> list(Long bookId) {
        List<BookReviewsVO> allReviews = bookReviewsMapper.getReviewsByBookId(bookId);
        Map<Long,BookReviewsVO> reviewsMap = new HashMap<>();
        for(BookReviewsVO bookReviewsVO : allReviews){
            reviewsMap.put(bookReviewsVO.getId(),bookReviewsVO);
        }
        List<BookReviewsVO> result = new ArrayList<>();
        for(BookReviewsVO bookReviewsVO : allReviews){
            if(bookReviewsVO.getParentReviewId() == 0 || bookReviewsVO.getParentReviewId() == null){
                result.add(bookReviewsVO);
            }else{
                BookReviewsVO parentReview = reviewsMap.get(bookReviewsVO.getParentReviewId());
                if(parentReview != null){
                    if (parentReview.getChildrenReviews() == null) {
                        parentReview.setChildrenReviews(new ArrayList<>());
                    }
                    parentReview.getChildrenReviews().add(bookReviewsVO);
                }
            }
        }
        return result;
    }
}
